package com.th.supcom.pds.impl.service.internal.phamapply;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import net.carefx.framework.exception.BusinessException;
import net.carefx.framework.util.ConvertUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.CollectionUtils;

import com.th.supcom.pds.domain.pojo.InpPhamApplyDetail;
import com.th.supcom.pds.domain.pojo.InpPhamApplyMaster;
import com.th.supcom.pds.domain.pojo.InpPhamApplyPatInfo;
import com.th.supcom.pds.domain.pojo.PdsPrescDetailCombine;
import com.th.supcom.pds.domain.vo.InpPhamApplyDetailVO;
import com.th.supcom.pds.domain.vo.InpPhamDispenseDetailVO;
import com.th.supcom.pds.impl.common.enums.BatchNumberManagerFlag;
import com.th.supcom.pds.impl.common.enums.InpChargeIndicator;
import com.th.supcom.pds.impl.common.enums.InpDispenseIndicator;
import com.th.supcom.pds.impl.common.enums.InpWithDrawType;
import com.th.supcom.pds.impl.common.enums.IsCancel;
import com.th.supcom.pds.impl.common.utils.ExceptionThrowHelper;
import com.th.supcom.pds.impl.service.internal.phamapply.chain.InPharmacyReturnServiceChain;
import com.th.supcom.pds.internal.api.PdsRecipefeeService;
import com.th.supcom.pds.internal.api.phamapply.InPharmacyReturnService;
import com.th.supcom.pds.internal.api.phamapply.InpPhamApplyDetailBasicService;
import com.th.supcom.pds.internal.api.phamapply.InpPhamApplyMasterBasicService;
import com.th.supcom.pds.medicare.api.AdapterPTSPatientInfoService;

/**
 * @author yzhang
 */
public class InPharmacyReturnServiceImpl implements InPharmacyReturnService,ApplicationContextAware
{
    /** 日志记录器. */
    public static final Logger s_logger = LoggerFactory.getLogger (InPharmacyReturnService.class);
    private InpPhamApplyMasterBasicService m_inpPhamApplyMasterBasicService;
    private InpPhamApplyDetailBasicService m_inpPhamApplyDetailBasicService;
    private PdsRecipefeeService m_pdsRecipefeeService;
    private AdapterPTSPatientInfoService m_adapterPTSPatientInfoService;
    ApplicationContext m_applicationContext = null;
    String m_inPharmacyReturnServiceChain = null;
    protected InPharmacyReturnServiceChain createInPharmacyReturnServiceChain (){
    	return (InPharmacyReturnServiceChain) m_applicationContext.getBean(m_inPharmacyReturnServiceChain);
    }

    public void setInPharmacyReturnServiceChain(String inPharmacyReturnServiceChaiName){
    	m_inPharmacyReturnServiceChain = inPharmacyReturnServiceChaiName;
    }
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
    		throws BeansException {
    	m_applicationContext = applicationContext;
    }
    /**
     * 通过电子退药单号修改明细为已退并记录修改条数.
     * 
     * @param InpPhamApplyDetailVO 传输对象.
     * @return 条数.
     */
    @Override
    public void modifyInPharmacyReturn (List <InpPhamApplyDetailVO> inpPhamApplyDetailVO, Map <String, Object> infoMap)
    {
        ExceptionThrowHelper.throwIllegalArgumentException (inpPhamApplyDetailVO.isEmpty (), "药房退药操作时，传入参数为空！");
        // 创建Chain并初始化chain上下文
        InPharmacyReturnServiceChain inPharmacyReturnServiceChain = createInPharmacyReturnServiceChain ();
        inPharmacyReturnServiceChain.getPhamDispenseContext ().setOperator ((String) infoMap.get ("operator"));
        inPharmacyReturnServiceChain.getPhamDispenseContext ().setNurseUnitCode ((String) infoMap.get ("nurseUnit"));
        inPharmacyReturnServiceChain.getPhamDispenseContext ().setApplyDetailVOList (inpPhamApplyDetailVO);

        List <InpPhamDispenseDetailVO> inpPhamDispenseDetailVOs = PhamDispenseConvertUtils.convertApplyToDispenseDetail (inpPhamApplyDetailVO, (String) infoMap.get ("operator"),
                                                                                                                         inpPhamApplyDetailVO.get (0).getExecDispensary ());

        // TODO
        List <String> phamStdCodeList = new ArrayList <String> ();

        Map <String, List <InpPhamDispenseDetailVO>> map = PhamDispenseConvertUtils.convertListToMapByPhamStdCode (inpPhamDispenseDetailVOs, phamStdCodeList);
        inPharmacyReturnServiceChain.getPhamDispenseContext ().setDispenseDetailByPhamStdCode (map);
        inPharmacyReturnServiceChain.getPhamDispenseContext ().setPhamStdCodeList (phamStdCodeList);
        inPharmacyReturnServiceChain.getPhamDispenseContext ().setInpPhamDispenseDetailVOList (inpPhamDispenseDetailVOs);

        if (InpWithDrawType.ReturnWithDrug.getEnumCode ().equals (inpPhamApplyDetailVO.get (0).getWithdrawType ()))
        {
            inPharmacyReturnServiceChain.inPharmacyReturnWithDrug ();
        }
        else
        {
            inPharmacyReturnServiceChain.inPharmacyReturnWithoutDrug ();
        }

    }

    private List <InpPhamApplyDetailVO> findPhamBatchFlagCode (List <InpPhamApplyDetailVO> detailList, String performedBy)
    {
        PdsPrescDetailCombine pdsPrescDetailCombine = new PdsPrescDetailCombine ();
        for (InpPhamApplyDetail inpDetail : detailList)
        {
            pdsPrescDetailCombine.setPhamCode (inpDetail.getPhamStdCode ());
            pdsPrescDetailCombine.setPerformedBy (performedBy);
            String flag = null;
            try
            {
                // flag = m_pdsRecipefeeService.findDrugBatchFlagByCode
                // (pdsPrescDetailCombine);
            }
            catch (Exception e)
            {
                s_logger.error ("查询药品批次号异常！");
                throw new BusinessException ("查询药品批次号异常，请联系计算机中心！", e);
            }
            inpDetail.setBatchNumberManagerFlag (flag == null ? BatchNumberManagerFlag.UnBatchManager.getEnumCode () : BatchNumberManagerFlag.OnBatchManager.getEnumCode ());
        }
        return detailList;
    }

    /**
     * 通过传输电子退药单号对应值查询表记录.
     * 
     * @param applyNo 传输对象.
     * @return InpPhamApplyDetailVO 结果对象.
     */
    public List <List <InpPhamApplyDetailVO>> findInpPhamApplyDetailByApplyNo (String applyNo, String patientId, String performedBy)
    {
        s_logger.error ("调用findInpPhamApplyDetailByApplyNo参数 ：applyNo:{},performedBy:{}", new Object[]
        { applyNo }, new Object[]
        { performedBy });
        ExceptionThrowHelper.throwIllegalArgumentException (applyNo == null && patientId == null, "输入电子单号和患者ID不能全为空!");
        ExceptionThrowHelper.throwIllegalArgumentException (performedBy == null, "错误！没有获取到本药房的药房编码！");
        List <List <InpPhamApplyDetailVO>> detailLists = new ArrayList <List <InpPhamApplyDetailVO>> ();
        if (null == patientId)
        {

            InpPhamApplyMaster inpPhamApplyMaster = new InpPhamApplyMaster ();
            inpPhamApplyMaster.setApplyNo (applyNo);
            List <InpPhamApplyMaster> masterList;
            masterList = m_inpPhamApplyMasterBasicService.findInpPhamApplyMasterListByExample (inpPhamApplyMaster);
            ExceptionThrowHelper.throwBusinessException (CollectionUtils.isEmpty (masterList), "查询不到相关信息，请重新输入！");
            ExceptionThrowHelper.throwBusinessException (IsCancel.YES.getEnumCode ().equals (masterList.get (0).getIsCancel ()), "该电子退药单已被作废，请使用新生成的电子退药单！");

            String masterNo = masterList.get (0).getApplyNo ();

            InpPhamApplyDetail inpPhamApplyDetail = new InpPhamApplyDetail ();
            inpPhamApplyDetail.setChargeIndicator (InpChargeIndicator.ReturnApplied.getEnumCode ());
            inpPhamApplyDetail.setDispenseIndicator (InpDispenseIndicator.HasReturnApplyed.getEnumCode ());
            inpPhamApplyDetail.setApplyNo (masterNo);

            List <InpPhamApplyDetailVO> detailList = m_inpPhamApplyDetailBasicService.findInpPhamApplyDetailListByExample (inpPhamApplyDetail);
            ExceptionThrowHelper.throwBusinessException (detailList.isEmpty (), "查询不到相关信息，请重新输入！");
            findPhamBatchFlagCode (detailList, performedBy);
            findPatiName (detailList);
            List <InpPhamApplyDetailVO> applyDetailVOs = ConvertUtils.convert (InpPhamApplyDetailVO.class, detailList);
            detailLists.add (applyDetailVOs);
        }
        else
        {
            InpPhamApplyDetailVO inpPhamApplyDetailVO = new InpPhamApplyDetailVO ();
            List <Long> paiVisitIdList = new ArrayList <Long> ();
            List <InpPhamApplyPatInfo> patInfos = m_adapterPTSPatientInfoService.findPatiInfoByPatientId (Long.parseLong (patientId));
            ExceptionThrowHelper.throwBusinessException (CollectionUtils.isEmpty (patInfos), "查询不到相关信息!");
            for (InpPhamApplyPatInfo inpPhamApplyPatInfo : patInfos)
            {
                paiVisitIdList.add (inpPhamApplyPatInfo.getPaiVisitId ());
            }
            inpPhamApplyDetailVO.setPaiVisitIdList (paiVisitIdList);
            inpPhamApplyDetailVO.setApplyNo (applyNo);
            inpPhamApplyDetailVO.setApplyDispensary (performedBy);
            List <InpPhamApplyDetail> detailList = m_inpPhamApplyDetailBasicService.findInpPhamApplyDetailForReturn (inpPhamApplyDetailVO);
            ExceptionThrowHelper.throwBusinessException (detailList.isEmpty (), "查询不到相关信息，请重新输入！");
            List <InpPhamApplyDetailVO> detailVoList = ConvertUtils.convert (InpPhamApplyDetailVO.class, detailList);
            findPhamBatchFlagCode (detailVoList, performedBy);
            findPatiName (detailVoList);
            detailLists = PhamApplyConvertUtils.groupDeatilListByApplyNo (detailVoList);
        }
        return detailLists;
    }

    /**
     * 查询患者姓名
     * 
     * @param detailList
     * @return
     */
    private List <InpPhamApplyDetailVO> findPatiName (List <InpPhamApplyDetailVO> detailList)
    {
        try
        {
            for (InpPhamApplyDetailVO inpDetail : detailList)
            {
                List <InpPhamApplyPatInfo> inpPhamApplyPatInfos = m_adapterPTSPatientInfoService.findPatiInfoByPatiVisitId (inpDetail.getPaiVisitId ());
                if (CollectionUtils.isEmpty (inpPhamApplyPatInfos))
                {
                    return detailList;
                }
                inpDetail.setPatiName (inpPhamApplyPatInfos.get (0).getPatName ());
                inpDetail.setPatientId (inpPhamApplyPatInfos.get (0).getPatientId ());
            }
            return detailList;
        }
        catch (Exception e)
        {
            s_logger.error ("查询患者姓名异常！");
            throw new BusinessException ("根据患者流水号查询患者姓名时出现异常！", e);
        }
    }

    public void setInpPhamApplyMasterBasicService (InpPhamApplyMasterBasicService inpPhamApplyMasterBasicService)
    {
        m_inpPhamApplyMasterBasicService = inpPhamApplyMasterBasicService;
    }

    public void setInpPhamApplyDetailBasicService (InpPhamApplyDetailBasicService inpPhamApplyDetailBasicService)
    {
        m_inpPhamApplyDetailBasicService = inpPhamApplyDetailBasicService;
    }

    public void setPdsRecipefeeService (PdsRecipefeeService pdsRecipefeeService)
    {
        m_pdsRecipefeeService = pdsRecipefeeService;
    }

    public void setAdapterPTSPatientInfoService (AdapterPTSPatientInfoService adapterPTSPatientInfoService)
    {
        m_adapterPTSPatientInfoService = adapterPTSPatientInfoService;
    }

    /** 公司版权信息. */
    public static final String copyright = "Copyright 2014, XuNuo Corporation";

    /** 提交路径. */
    public static final String SCC_BRANCH = "$URL$";

    /** 提交日期. */
    public static final String SCC_LAST_MODIFICATION_DATE = "$Date$";

    /** 最终修改人员. */
    public static final String SCC_LAST_MODIFIER_NAME = "$Author$";

    /** 最终版本号. */
    public static final String SCC_REVISION = "$Revision$";
}
